package com.mike.worm;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStreamReader;
import java.util.Map;

/**
 * Http客户端工具类。
 * Created by zhpeng2 on 2016/10/25.
 */
public final class HttpUtils {
    private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);

    /**
     * HTTP POST调用接口。
     *
     * @param "test"      消息ID，null时自动生成。
     * @param url         接口地址。
     * @param content     消息内容。
     * @param contentType 消息内容类型。
     * @param timeout     超时时间(ms)，null使用默认超时时间。
     * @param headers     请求的header头。
     * @return 接口响应内容。
     */
    public static String post(String url, String content, String contentType, Integer timeout, Map<String, String> headers) {
//        if (StringUtils.isBlank("test")) {
//            "test" = MD5Utils.to16md5(UUID.randomUUID().toString());
//        }
        HttpPost post = null;
        HttpResponse response = null;
        InputStreamReader isr = null;
        try {
            post = new HttpPost(url);
            post.setHeader("Referer", post.getURI().getScheme() + "://" + post.getURI().getAuthority());
            post.setHeader("Origin", post.getURI().getScheme() + "://" + post.getURI().getAuthority());
            post.setHeader("Host", post.getURI().getAuthority());
            if (contentType != null) {
                post.setHeader("Content-Type", contentType);
            }
            if (headers != null && !headers.isEmpty()) {
                for (Map.Entry<String, String> pair : headers.entrySet()) {
                    if (StringUtils.isNotBlank(pair.getKey()))
                        post.setHeader(pair.getKey(), pair.getValue());
                }
            }
            if (content != null) {
                HttpEntity entity = new StringEntity(content, "UTF-8");
                post.setEntity(entity);
            }
            if (timeout != null) {
                RequestConfig rc = RequestConfig.custom()
                        .setConnectionRequestTimeout(timeout)
                        .setConnectTimeout(timeout)
                        .setSocketTimeout(timeout)
                        .build();
                post.setConfig(rc);
            }
            HttpClient httpClient = httpClient();
            response = httpClient.execute(post);
            log.info("**[{}]**接口调用：method=POST, url={}, body={}, status-code={}**", new Object[]{"test", url, content, response.getStatusLine().getStatusCode()});
            if (response.getStatusLine().getStatusCode() != 200) {
                // log.error("**[{}]**HTTP接口调用失败，http code: {}**", "test", response.getStatusLine().getStatusCode());
                return null;
            }
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity == null) {
                log.info("**[{}]**HTTP接口返回结果为空，method=POST, url={}, body={}**", new Object[]{"test", url, content});
                return null;
            }
            isr = new InputStreamReader(responseEntity.getContent(), "UTF-8");
            StringBuilder sb = new StringBuilder();
            char[] cbuf = new char[1024];
            int read;
            while ((read = isr.read(cbuf, 0, cbuf.length)) != -1) {
                if (read > 0)
                    sb.append(cbuf, 0, read);
            }
            log.info("**[{}]**HTTP接口返回结果：{}**", "test", sb.toString());
            return sb.toString();
        } catch (Throwable e) {
            log.error(String.format("**[%s]**HTTP接口异常：method=POST, url=%s, body=%s, %s**", "test", url, content, e.getMessage()), e);
            return null;
        } finally {
            //close(null, post, response, isr);
        }
    }

    private static HttpClient httpClient() {
//        return LazyHolder.INSTANCE;
        return HttpClientBuilder.create()
//                .setMaxConnTotal(maxTotal)
//                .setMaxConnPerRoute(defaultMaxPerRoute)
//                .setDefaultRequestConfig(rc)
//                .setConnectionManager(cm)
                .build();
    }

}
